/*********************************************************
 *********************************************************
 ********************                  *******************
 *************                                ************
 *******                  _oo0oo_                  *******
 ***                     o8888888o                     ***
 *                       88" . "88                       *
 *                       (| -_- |)                       *
 *                       0\  =  /0                       *
 *                     ___/`---'\___                     *
 *                   .' \\|     |// '.                   *
 *                  / \\|||  :  |||// \                  *
 *                 / _||||| -:- |||||- \                 *
 *                |   | \\\  -  /// |   |                *
 *                | \_|  ''\---/''  |_/ |                *
 *                \  .-\__  '-'  ___/-. /                *
 *              ___'. .'  /--.--\  `. .'___              *
 *           ."" '<  `.___\_<|>_/___.' >' "".            *
 *          | | :  `- \`.;`\ _ /`;.`/ - ` : | |          *
 *          \  \ `_.   \_ __\ /__ _/   .-` /  /          *
 *      =====`-.____`.___ \_____/___.-`___.-'=====       *
 *                        `=---='                        *
 *      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~      *
 *********__佛祖保佑__永无BUG__验收通过__钞票多多__*********
 *********************************************************/
package org.jbase.coder.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.beetl.sql.core.JavaType;
import org.beetl.sql.core.TailBean;
import org.beetl.sql.core.db.ColDesc;
import org.beetl.sql.core.db.MetadataManager;
import org.beetl.sql.core.db.TableDesc;
import org.jbase.coder.component.CoderBuilder;
import org.jbase.coder.component.fupin.CbFupinDao;
import org.jbase.coder.component.fupin.CbFupinEntity;
import org.jbase.coder.component.fupin.CbFupinMd;
import org.jbase.coder.component.fupin.CbFupinService;
import org.jbase.coder.component.hebim.CbHebimAdd;
import org.jbase.coder.component.hebim.CbHebimController;
import org.jbase.coder.component.hebim.CbHebimDao;
import org.jbase.coder.component.hebim.CbHebimEdit;
import org.jbase.coder.component.hebim.CbHebimEntity;
import org.jbase.coder.component.hebim.CbHebimIndex;
import org.jbase.coder.component.hebim.CbHebimMd;
import org.jbase.coder.component.hebim.CbHebimService;
import org.jbase.coder.component.hebim.CbHebimShow;
import org.jbase.coder.component.jbase.CBEntity;
import org.jbase.coder.component.jbase.CBFrontAdd;
import org.jbase.coder.component.jbase.CBFrontController;
import org.jbase.coder.component.jbase.CBFrontEdit;
import org.jbase.coder.component.jbase.CBFrontList;
import org.jbase.coder.component.jbase.CBService;
import org.jbase.coder.component.xwl.XwlAdd;
import org.jbase.coder.component.xwl.XwlApiService;
import org.jbase.coder.component.xwl.XwlBackendController;
import org.jbase.coder.component.xwl.XwlBackendService;
import org.jbase.coder.component.xwl.XwlDomain;
import org.jbase.coder.component.xwl.XwlEdit;
import org.jbase.coder.component.xwl.XwlFrontController;
import org.jbase.coder.component.xwl.XwlFrontService;
import org.jbase.coder.component.xwl.XwlImplDao;
import org.jbase.coder.component.xwl.XwlImplService;
import org.jbase.coder.component.xwl.XwlIndex;
import org.jbase.coder.component.xwl.XwlShow;
import org.jbase.common.service.BaseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * Project: jb_coder <br/>
 * File: CoderService.java <br/>
 * Class: org.jbase.coder.service.CoderService <br/>
 * Description: <描述类的功能>. <br/>
 * Copyright: Copyright (c) 2011 <br/>
 * Company: http://www.yxtsoft.com/ <br/>
 * Makedate: 2016年7月13日 下午4:03:52 <br/>
 * 
 * @author liuzhanhong
 * @version 1.0
 * @since 1.0
 */
@Service
public class CoderService extends BaseService {

	private static final Logger L = LoggerFactory.getLogger(CoderService.class);

	public List<Map<String, Object>> listTables() {

		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		MetadataManager metaDataManager = sql.getMetaDataManager();
		Set<String> allTable = metaDataManager.allTable();
		for (String tablename : allTable) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("tablename", tablename);
			TableDesc table = metaDataManager.getTable(tablename);
			Set<String> cols = table.getCols();
			int i = 0;
			int hasid = 0;
			for (String col : cols) {
				if ("ID".equals(col)) {
					hasid = 1;
					i++;
				} else if ("SID".equals(col) || "LOCKVERSION".equals(col) || "CREATETIME".equals(col)
						|| "MODIFYTIME".equals(col) || "STATE".equals(col) || "ISENABLE".equals(col)
						|| "ISDELETE".equals(col) || "REMARKS".equals(col) || "CREATEBYSID".equals(col)
						|| "UPDATEBYSID".equals(col)) {
					i++;
				}
			}

			map.put("hasid", hasid);
			map.put("hasext", i);
			list.add(map);
		}

		return list;
	}

	/**
	 * 描述 : <描述函数实现的功能>. <br/>
	 * <p>
	 * 
	 * @param params
	 */
	public void genCode(Map<String, Object> params) {
		String tablename = params.get("tablename").toString();
		String modulename = params.get("modulename").toString();
		String entityclassname = params.get("entityclassname").toString();
		genCode(tablename, modulename, entityclassname);
	}

	private String getTableDesc(String tablename) {

		String sqls = "SELECT TABLE_NAME, TABLE_COMMENT FROM information_schema.tables where TABLE_NAME=#tname#";
		Map<String, String> mppp = new HashMap<String, String>();
		mppp.put("tname", tablename);
		List<TailBean> execute = sql.execute(sqls, TailBean.class, mppp);
		String td = "" + execute.get(0).get("TABLE_COMMENT");
		return td;
	}

	public void genCode(String tablename, String modulename, String entityclassname) {

		String td = getTableDesc(tablename);

		MetadataManager mm = sql.getMetaDataManager();

		TableDesc tableDesc = mm.getTable(tablename);

		List<Map<String, Object>> attrs = genTableAttribles(tableDesc);

		L.debug("生成 {}模块,{}表 代码___start", modulename, tablename);
		new CBEntity().genCode(tablename, modulename, entityclassname, td, attrs);
		new CBService().genCode(tablename, modulename, entityclassname, td, attrs);
		new CBFrontController().genCode(tablename, modulename, entityclassname, td, attrs);
		new CBFrontAdd().genCode(tablename, modulename, entityclassname, td, attrs);
		new CBFrontEdit().genCode(tablename, modulename, entityclassname, td, attrs);
		new CBFrontList().genCode(tablename, modulename, entityclassname, td, attrs);
		L.debug("生成 {}模块,{}表 代码___end", modulename, tablename);
	}

	/**
	 * 描述 : <描述函数实现的功能>. <br/>
	 * <p>
	 * 
	 * @param tableDesc
	 * @param cols
	 * @param attrs
	 */
	private List<Map<String, Object>> genTableAttribles(TableDesc tableDesc) {
		List<Map<String, Object>> attrs = new ArrayList<Map<String, Object>>();
		Set<String> cols = tableDesc.getCols();
		for (String col : cols) {
			if (!("id".equalsIgnoreCase(col) || "SID".equalsIgnoreCase(col) || "LOCKVERSION".equalsIgnoreCase(col)
					|| "CREATETIME".equalsIgnoreCase(col) || "MODIFYTIME".equalsIgnoreCase(col)
					|| "STATE".equalsIgnoreCase(col) || "ISENABLE".equalsIgnoreCase(col)
					|| "ISDELETE".equalsIgnoreCase(col) || "REMARKS".equalsIgnoreCase(col)
					|| "CREATEBYSID".equalsIgnoreCase(col) || "UPDATEBYSID".equalsIgnoreCase(col))) {

				ColDesc desc = tableDesc.getColDesc(col);
				Map<String, Object> attr = new HashMap<String, Object>();

				if (StringUtils.isBlank(desc.remark))
					attr.put("comment", desc.colName);
				else
					attr.put("comment", desc.remark);

				attr.put("name", desc.colName);
				attr.put("gname", desc.colName.substring(0, 1).toUpperCase() + desc.colName.substring(1));

				String type = JavaType.getType(desc.sqlType, desc.size, desc.digit);
				attr.put("type", type);
				attrs.add(attr);
			}
		}
		return attrs;
	}

	private List<Map<String, Object>> genXwlTableAttribles(TableDesc tableDesc) {
		List<Map<String, Object>> attrs = new ArrayList<Map<String, Object>>();
		Set<String> cols = tableDesc.getCols();
		for (String col : cols) {
			if (!("id".equalsIgnoreCase(col))) {

				ColDesc desc = tableDesc.getColDesc(col);
				Map<String, Object> attr = new HashMap<String, Object>();

				String colName = desc.colName;

				if (StringUtils.isBlank(desc.remark))
					attr.put("comment", colName);
				else
					attr.put("comment", desc.remark);

				colName = ccolName(colName);
				attr.put("name", colName);
				attr.put("gname", colName.substring(0, 1).toUpperCase() + colName.substring(1));

				String type = JavaType.getType(desc.sqlType, desc.size, desc.digit);
				attr.put("type", type);
				attrs.add(attr);
			}
		}
		return attrs;
	}

	private String ccolName(String colName) {
		String[] names = colName.split("_");
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < names.length; i++) {
			if (i == 0) {
				sb.append(names[i].substring(0, 1).toLowerCase()).append(names[i].substring(1));
			} else {
				sb.append(names[i].substring(0, 1).toUpperCase()).append(names[i].substring(1));
			}
		}
		return sb.toString();
	}

	/**
	 * 描述 : <描述函数实现的功能>. <br/>
	 * <p>
	 * 
	 * @param tbnames
	 */
	public void genCodeByTableList(String[] tbnames) {

		// genXwlCode(tbnames);
		// genHebimCode(tbnames);
		genAdminCode(tbnames);
		// genFupinCode(tbnames);
	}

	private void genXwlCode(String[] tbnames) {
		String modulename = "hebim";
		MetadataManager mm = sql.getMetaDataManager();

		for (String tablename : tbnames) {

			String td = getTableDesc(tablename);

			TableDesc tableDesc = mm.getTable(tablename);

			List<Map<String, Object>> attrs = genXwlTableAttribles(tableDesc);

			String entityclassname = getEntityClassNameByTableName(tablename, 0);
			L.debug("生成 {}模块,{}表 代码___start", modulename, tablename);
			new XwlDomain().genCode(tablename, modulename, entityclassname, td, attrs);
			new XwlApiService().genCode(tablename, modulename, entityclassname, td, attrs);
			new XwlImplDao().genCode(tablename, modulename, entityclassname, td, attrs);
			new XwlImplService().genCode(tablename, modulename, entityclassname, td, attrs);
			new XwlBackendService().genCode(tablename, modulename, entityclassname, td, attrs);
			new XwlBackendController().genCode(tablename, modulename, entityclassname, td, attrs);
			new XwlFrontService().genCode(tablename, modulename, entityclassname, td, attrs);
			new XwlFrontController().genCode(tablename, modulename, entityclassname, td, attrs);
			new XwlAdd().genCode(tablename, modulename, entityclassname, td, attrs);
			new XwlEdit().genCode(tablename, modulename, entityclassname, td, attrs);
			new XwlIndex().genCode(tablename, modulename, entityclassname, td, attrs);
			new XwlShow().genCode(tablename, modulename, entityclassname, td, attrs);
			L.debug("生成 {}模块,{}表 代码___end", modulename, tablename);
		}
	}

	private void genHebimCode(String[] tbnames) {
		String modulename = "hebim";
		MetadataManager mm = sql.getMetaDataManager();

		for (String tablename : tbnames) {

			String td = getTableDesc(tablename);
			TableDesc tableDesc = mm.getTable(tablename);

			List<Map<String, Object>> attrs = genTableAttribles(tableDesc);

			String entityclassname = getEntityClassNameByTableName(tablename, 1);
			L.debug("生成 {}模块,{}表 代码___start", modulename, tablename);
			new CbHebimAdd().genCode(tablename, modulename, entityclassname, td, attrs);
			new CbHebimController().genCode(tablename, modulename, entityclassname, td, attrs);
			new CbHebimDao().genCode(tablename, modulename, entityclassname, td, attrs);
			new CbHebimEdit().genCode(tablename, modulename, entityclassname, td, attrs);
			new CbHebimEntity().genCode(tablename, modulename, entityclassname, td, attrs);
			new CbHebimIndex().genCode(tablename, modulename, entityclassname, td, attrs);
			new CbHebimMd().genCode(tablename, modulename, entityclassname, td, attrs);
			new CbHebimService().genCode(tablename, modulename, entityclassname, td, attrs);
			new CbHebimShow().genCode(tablename, modulename, entityclassname, td, attrs);
			L.debug("生成 {}模块,{}表 代码___end", modulename, tablename);
		}
	}

	private void genAdminCode(String[] tbnames) {
		genCode("admin", tbnames);
	}

	private void genCode(String modulename, String[] tbnames) {
		CoderBuilder cb = new CoderBuilder(modulename);
		genCode(cb, tbnames);
	}

	private void genCode(CoderBuilder cb, String[] tbnames) {
		MetadataManager mm = sql.getMetaDataManager();

		for (String tablename : tbnames) {

			String td = getTableDesc(tablename);
			TableDesc tableDesc = mm.getTable(tablename);

			List<Map<String, Object>> attrs = genTableAttribles(tableDesc);

			String entityclassname = getEntityClassNameByTableName(tablename, 0);
			L.debug("生成 表--{} 代码___start", tablename);

			cb.gen(tablename, td, entityclassname, attrs);
			L.debug("生成 表--{} 代码___end", tablename);
		}
	}

	private void genFupinCode(String[] tbnames) {
		String modulename = "fupin";
		MetadataManager mm = sql.getMetaDataManager();

		for (String tablename : tbnames) {

			String td = getTableDesc(tablename);
			TableDesc tableDesc = mm.getTable(tablename);

			List<Map<String, Object>> attrs = genTableAttribles(tableDesc);

			String entityclassname = getEntityClassNameByTableName(tablename, 0);
			L.debug("生成 {}模块,{}表 代码___start", modulename, tablename);
			new CbFupinDao().genCode(tablename, modulename, entityclassname, td, attrs);
			new CbFupinEntity().genCode(tablename, modulename, entityclassname, td, attrs);
			new CbFupinMd().genCode(tablename, modulename, entityclassname, td, attrs);
			new CbFupinService().genCode(tablename, modulename, entityclassname, td, attrs);
			L.debug("生成 {}模块,{}表 代码___end", modulename, tablename);
		}
	}

	private String getEntityClassNameByTableName(String tablename, int stip) {
		String cname = tablename.toLowerCase();
		String[] names = cname.split("_");
		StringBuilder sb = new StringBuilder();
		for (int i = stip; i < names.length; i++) {
			sb.append(names[i].substring(0, 1).toUpperCase()).append(names[i].substring(1));
		}
		return sb.toString();
	}
}
